﻿using UnityEngine;
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;

public class PlayerKingdom : Kingdom
{
	// for test
	public static int turncount = 0;

	private List<Fleet.SolarFleet> m_KingdomFleets = new List<Fleet.SolarFleet>();


	// getters and setters
	public List<Fleet.SolarFleet> KingdomFleets
	{
		get { return m_KingdomFleets; }
		set { m_KingdomFleets = value; }
	}


	// for camera display
	public string pOwnedTechString = "";				// display names of technologies developed
	public string pUnlockedTechString = "";			// newly found technologies
	public string pDevTechString = "";					// technologies under development

	public PlayerKingdom(Race race) : base(race)
	{
		this.KingName = Core.PlayerKingName;
	}


	// ISerializable
	public override void Serialize(GenericWriter writer)
	{
		base.Serialize(writer);
		writer.Write((int)0); // version

		writer.Write((string)pOwnedTechString);
		writer.Write((string)pUnlockedTechString);
		writer.Write((string)pDevTechString);
	}

	public override void Deserialize(GenericReader reader)
	{
		base.Deserialize(reader);
		int version = reader.ReadInt();

		pOwnedTechString = reader.ReadString();
		pUnlockedTechString = reader.ReadString();
		pDevTechString = reader.ReadString();
	}


	// class methods
	public override void OnBeginTurn()
	{
		base.OnBeginTurn();

		List<Fleet> ldock = new List<Fleet>();				// store fleets to be docked

		foreach (SolarPlanet sp in Planets)
			foreach (Fleet fl in sp.pSolar.Launching)
			{
				if (fl.Belong == this && MoveFleetLocation(fl))			// must detect Belong or else other kingdom's ships are launched
				{
					if (fl.Turn < 1)					// destination reached
						ldock.Add(fl);
				}
			}

		if (ldock.Count > 0)
			MovingFleets(ldock);
	}

	public override void OnTurn()
	{
		List<TechByCost> playerTech = new List<TechByCost>();

		// to get player selected technologies for advancement
		if (Dev.Count < Kingdom.MaxTechDev)
			playerTech = GameObject.Find("guiCamera").GetComponent<GuiCamera>().nTech;

		// to add player selected or random technology to pool
		foreach (TechByCost tcost in playerTech)
			if (Dev.Count < Kingdom.MaxTechDev)
				Dev.Add(tcost);

		base.OnTurn();

		PrepareTechDisplay();
	}

	public override void OnEndTurn()
	{
		base.OnEndTurn();

		List<StarSystem> lstars = new List<StarSystem>();

		foreach (SolarPlanet sp in this.Planets)
		{
			if (sp.pSolar.SolarColony.ContainsKey(this as Kingdom) && (int)sp.pSolar.SolarColony[this as Kingdom] > 0)
			{
				lstars.Add(sp.pSolar);

				turncount++;
				Debug.Log("#" + turncount.ToString() + ", Race: " + Race.RaceType.ToString() + ", Colony: " + (int)sp.pSolar.SolarColony[this as Kingdom]);
			}

			if (lstars.Count > 0)
				Core.oMainCam.GetComponent<InitCamera>().lSolars = lstars;
			
			// to do other solar related tasks
			
		}
	}

	public override bool MovingFleets(List<Fleet> lflts)
	{
		// to handle docking ships
		foreach (Fleet fl in lflts)
		{
			bool destroy = false;
			DockingNewSolar(fl, fl.Dest, out destroy);

			if (destroy)					// to destroy used outpost
				DestroyFleet(fl);

			if (fl is ColonyShip && fl.Home.OwnedBy.Contains(this) && !IsPlanetOwned(fl.Home))		// new home updated in "DockingNewSolar()
			{
				Core.oMainCam.GetComponent<InitCamera>().RunVisualStar(fl.Home);
				Core.oGuiCam.GetComponent<GuiCamera>().toColony = true;
			}
		}

		return base.MovingFleets(lflts);
	}

	public bool SettleColonyShip(StarSystem dest, Planet pl)
	{
		int cnt = 0;
		Fleet destroy = null;

		foreach (Fleet fl in dest.Docking)
			if (fl is ColonyShip && fl.Belong == this && cnt == 0)
			{
				destroy = fl;
				cnt++;
			}

		if (cnt == 0)
		{
			Debug.Log("Failed to find colony ship to dock! " + dest.StarName);
			return false;
		}

		if (destroy != null)
			DestroyFleet(destroy);

		RegisterNewColony(this, pl, false);

		return true;
	}

	public bool GatherKingdomFleets(StarSystem dest, bool flag)			// flag - whether to gather midway ships
	{
		m_KingdomFleets = new List<Fleet.SolarFleet>();
		Fleet.SolarFleet sfd;
		Fleet.SelectFleet sel;

		int[] adist = new int[2] { 0, 0 };

		foreach (SolarPlanet sp in this.Planets)
		{
			if (sp.pSolar.Docking.Count > 0 || sp.pSolar.Launching.Count > 0)
			{
				sfd = new Fleet.SolarFleet(sp.pSolar);

				adist = GetDistanceTurn(sp.pSolar, dest, this.Drive + this.DriveBonus);
				sfd.pDistance = adist[0] / 1000;
				sfd.pTurn = adist[1];

				foreach (Fleet fl in sp.pSolar.Docking)						// fleet is docking
					if (fl.Belong == this)
					{
						sel = new Fleet.SelectFleet(fl);
						sel.pSelected = true;
						sfd.Add(sel, 0);
					}

				foreach (Fleet flh in sp.pSolar.Launching)
					if (flh.Belong == this)
					{
						sel = new Fleet.SelectFleet(flh);
						sel.pSelected = true;

						if (flh.Location == sp.pSolar.Location)				// fleet is to be launched
						{
							sfd.Add(sel, 1);
						}
						else if (flag)																// fleet already launched
						{
							sfd.Add(sel, 2);
						}
					}

				m_KingdomFleets.Add(sfd);
				m_KingdomFleets.Sort(new Fleet.LocSorter());
			}
		}

			return true;
	}

	public void PrepareTechDisplay()
	{
		pOwnedTechString = "";
		pUnlockedTechString = "";
		pDevTechString = "";

		foreach (TechByCost tbc in Owned)
			pOwnedTechString += "\n" + tbc.pName;

		if (pOwnedTechString.Length > 0)
			pOwnedTechString = pOwnedTechString.Substring(1);

		foreach (Technology tech in Unlocked)
			pUnlockedTechString += "\n" + Utility.SplitName(tech.Name.ToString());

		if (pUnlockedTechString.Length > 0)
			pUnlockedTechString = pUnlockedTechString.Substring(1);

		foreach (TechByCost tcost in Dev)
			pDevTechString += "\n" + tcost.pName;

		if (pDevTechString.Length > 0)
			pDevTechString = pDevTechString.Substring(1);
	}

}
